package com.merry.aop.advisor;

import org.aopalliance.aop.Advice;
import org.aopalliance.intercept.Interceptor;
import org.aopalliance.intercept.MethodInterceptor;
import org.springframework.aop.AfterReturningAdvice;
import org.springframework.aop.BeforeAdvice;
import org.springframework.aop.Pointcut;
import org.springframework.aop.ThrowsAdvice;

/**
 * 基础接口用于保存 AOP的 <b>{@link Advice}</b>（在连接点采取的行动）
 * 和确定 Advice 的适用性的过滤器（如<b>{@link Pointcut}</b>）。
 * <i>此接口不供Spring用户使用，但允许通用性以支持不同类型的建议。
 *
 * <p>Spring AOP基于通过方法拦截提供的Advice，符合AOP联盟拦截API。
 * Advisor接口允许支持不同类型的{@code Advice}，例如建议<b>Before</b>和<b>After</b>，这些建议不需要使用{@link Interceptor}来实现。
 */
public interface Advisor {

    /**
     * 一个空的 Advice 集合，在 {@link #getAdvice()} 方法中返回。表示当前方法，不需要代理。
     */
    Advice EMPTY_ADVICE = new Advice() {};


    /**
     * 返回一部分的 {@link Advice}的实现类，需要和 Pointcut 匹配的类。
     * 只返回下面四个接口的实现类。
     * @see MethodInterceptor
     * @see BeforeAdvice
     * @see ThrowsAdvice
     * @see AfterReturningAdvice
     */
    Advice getAdvice();

    /**
     * 返回此 Advice 是与<b>特定实例相关联</b>（例如，创建混入）还是与从同一Spring bean工厂获得的 Advice 类的所有<b>实例共享</b>。
     * <p><b>请注意，该框架当前未使用此方法。</b>
     * 典型的Advisor实现总是返回true。使用单例/原型bean定义或适当的程序化代理创建，以确保顾问具有正确的生命周期模型。
     */
    boolean isPerInstance();

}
